<template>
    <div ref="container" class="cube-scene">
        <!-- 货物信息弹窗 -->
        <div v-if="selectedCargo" class="cargo-info-popup">
            <h3>货物详情</h3>
            <p><strong>位置:</strong> {{ selectedCargo.position }}</p>
            <p><strong>名称:</strong> {{ selectedCargo.name || '无' }}</p>
            <p><strong>料号:</strong> {{ selectedCargo.materialCode || '无' }}</p>
            <p><strong>批号:</strong> {{ selectedCargo.materialCode || '无' }}</p>
            <p><strong>数量:</strong> {{ selectedCargo.materialCode || '无' }}</p>
            <p><strong>生产日期:</strong> {{ selectedCargo.materialCode || 0 }}</p>
            <p><strong>保质期:</strong> {{ selectedCargo.materialCode || '无' }}</p>
            <p><strong>生产班次:</strong> {{ selectedCargo.materialCode || '无' }}</p>
            <h3>拆包领用</h3>
            <p>质检1</p>
            <p>质检2</p>
            <p>质检3</p>

            <!-- <p><strong>拆包领用:</strong> {{ selectedCargo.materialCode || '无' }}</p> -->
            <!-- <p><strong>状态:</strong> {{ selectedCargo.hasGoods ? '有货' : '无货' }}</p> -->
        </div>
        <!-- 右击操作弹窗 -->
        <div v-if="showContextMenu" class="context-menu"
            :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }">
            <div class="iconClose" @click="closeContextMenu">
                <Icon type="md-close" color="#000" size="20" />
            </div>
            <h4>货位操作 - {{ selectedCargoPosition }}</h4>
            <div class="optionsMenu">
                <div class="switch">
                    <Switch size="large">
                        <template #open>
                            <span>上架</span>
                        </template>
                        <template #close>
                            <span>下架</span>
                        </template>
                    </Switch>
                </div>
                <Button type="info" @click="handleSales">销售出货</Button>
                <Button type="info" @click="handleInventory">领用库存</Button>
                <Button type="info" @click="handleInspection">商品质检</Button>
                <Button type="info" @click="handleDetails">查看详情</Button>
            </div>
        </div>
        

        <!-- 放置货架提示 -->
        <div v-if="isPlacingShelf" class="placement-hint">
            <p>点击地面放置货架(绿色区域可放置)</p>
            <Button type="error" @click="cancelShelfPlacement">取消生成</Button>
        </div>
        <!-- 边界警告 -->
        <div v-if="showBoundaryWarning" class="boundary-warning">
            货架超出仓库边界，无法放置！
        </div>

    </div>
</template>

<script setup>

import { ref, onMounted, onUnmounted, watch, reactive, defineProps } from 'vue'
import * as THREE from 'three'

const props = defineProps({
    newShelfConfig: {
        type: Object,
        default: {
            columns: 3,
            levels: 4,
            depth: 1,
            depthLength: 0.5,
            columnWidth: 0.5,
            levelHeight: 0.5,
            pillarColor: 0x2196F3,
            shelfColor: 0x1976D2
        }
    }
})
const newShelfConfig = reactive(props.newShelfConfig)
const container = ref(null)
let scene, camera, renderer, controls, raycaster, mouse
let walls = [];
let shelves = []; // 改为局部变量而不是响应式引用
let selectedCell = null; // 当前选中的货位
let cellLabels = []; // 存储所有货位标签
let textureLoader = new THREE.TextureLoader()
let borderTexture = null
let floorTexture = null //添加地板纹理
let shelfLabels = []; // 存储货架标签
let cargoCubes = []; // 存储所有货物立方体
const showContextMenu = ref(false);
const menuPosition = reactive({ x: 0, y: 0 });
const shelfStatus = ref(false);
const selectedCargoPosition = ref('');

// 货物数据示例
const cargoData = reactive({
    // 格式: '货架-层-列-深': { hasGoods: boolean, name: string, materialCode: string }
    '货架1-1-1-1-1': { hasGoods: true, name: '电子元件', materialCode: 'EC-001' },
    '货架1-2-1-2-1': { hasGoods: false, name: '', materialCode: '' },
    '货架2-2-2-3-1': { hasGoods: true, name: '电路板', materialCode: 'PCB-002' },
    // 可以添加更多货物数据...
});

// 选中的货物信息
const selectedCargo = ref(null);

// 货架布局参数
const rows = ref(2)
const cols = ref(3)
const spacing = ref(3)
// 货架配置
const shelfConfig = ref({
    columns: 3,
    columnWidth: 0.5,
    levels: 4,
    levelHeight: 0.5,
    depth: 1,
    depthLength: 0.5,
    pillarColor: 0x2196F3,
    shelfColor: 0x1976D2
})

// 新增变量用于货架拖拽生成
const isPlacingShelf = ref(false);
const showBoundaryWarning = ref(false);
const canPlaceShelf = ref(false);
// 仓库边界参数
const warehouseBounds = {
    minX: -9.8,
    maxX: 9.8,
    minZ: -9.8,
    maxZ: 9.8
};
// 生成新的货架
// const newShelfConfig = reactive({
//     columns: 3,
//     levels: 4,
//     depth: 1, // 深度方向货位数，默认为1
//     depthLength: 0.5, // 每个货位的深度
//     columnWidth: 0.5, // 每个货位的宽度
//     levelHeight: 0.5, // 每层的高度
//     pillarColor: 0x2196F3,
//     shelfColor: 0x1976D2
// });
const shelfCounter = ref(1); // 用于生成货架名称的计数器
let previewShelf = null; // 预览货架的引用
const floorPlane = ref(null); // 地板的引用，用于检测点击位置

onMounted(async () => {
    // 先加载纹理
    await loadTextures()
    await init()
    animate()
    generateShelves()

    // 添加点击事件监听
    if (renderer) {
        renderer.domElement.addEventListener('click', onCanvasClick);
        // 添加右击事件监听
        renderer.domElement.addEventListener('contextmenu', onCanvasRightClick);
    }
    // 添加全局点击监听以关闭菜单
    // document.addEventListener('click', closeContextMenu);
})
onUnmounted(() => {
    if (renderer) {
        renderer.dispose()
        renderer.domElement.removeEventListener('click', onCanvasClick);
        renderer.domElement.removeEventListener('contextmenu', onCanvasRightClick);
    }
    // document.removeEventListener('click', closeContextMenu);
    if (controls) {
        controls.dispose()
    }
    // 清理货架
    shelves.forEach(shelf => {
        scene.remove(shelf)
    })
    // 清理标签
    cellLabels.forEach(label => {
        scene.remove(label)
    })
    shelfLabels.forEach(label => {
        scene.remove(label)
    })
    // 清理货物立方体
    cargoCubes.forEach(cube => {
        scene.remove(cube.mesh);
    });
    // 移除鼠标移动监听
    if (renderer) {
        renderer.domElement.removeEventListener('mousemove', onMouseMove);
    }

    // 移除预览货架
    if (previewShelf) {
        scene.remove(previewShelf);
    }
    window.removeEventListener('resize', onWindowResize)
})



// 处理画布右击事件
const onCanvasRightClick = (event) => {
    event.preventDefault();
    // 计算鼠标在归一化设备坐标中的位置
    const rect = renderer.domElement.getBoundingClientRect();
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera(mouse, camera);

    // 计算物体和射线的交点
    const intersects = raycaster.intersectObjects(scene.children, true);

    // 查找货位交互平面
    for (let i = 0; i < intersects.length; i++) {
        const object = intersects[i].object;
        // 检查是否右击了货物立方体
        if (object.userData && object.userData.isCargoCube) {
            // 高亮选中的货物立方体
            highlightCargoCube(object);
            // 显示货物信息
            selectedCargo.value = {
                position: object.userData.position,
                name: object.userData.cargoInfo.name,
                materialCode: object.userData.cargoInfo.materialCode,
                hasGoods: object.userData.cargoInfo.hasGoods
            };

            // 设置菜单位置
            menuPosition.x = event.clientX;
            menuPosition.y = event.clientY;

            // 设置选中货位和上架状态
            selectedCargoPosition.value = object.userData.position;
            shelfStatus.value = object.userData.cargoInfo.hasGoods;
            // 显示菜单
            showContextMenu.value = true;
            return;
        }
    }
    // 如果没有点击到货物，关闭菜单
    closeContextMenu();
}
// 关闭右击菜单
const closeContextMenu = () => {
    showContextMenu.value = false;
}
// 上架/下架操作
watch(shelfStatus, (newValue) => {
    // 在实际应用中，这里应该更新货物状态
    console.log(`货位 ${selectedCargoPosition.value} 状态改为: ${newValue ? '上架' : '下架'}`);

    // 更新3D场景中的货物显示状态
    updateCargoStatus(selectedCargoPosition.value, newValue);
})
// 更新货物状态
const updateCargoStatus = (position, hasGoods) => {
    // 找到对应的货物立方体并更新状态
    for (const cubeData of cargoCubes) {
        if (cubeData.position === position) {
            // 更新颜色
            const color = hasGoods ? 0x00ff00 : 0xff0000;
            const emissive = hasGoods ? 0x003300 : 0x330000;
            cubeData.mesh.material.color.setHex(color);
            cubeData.mesh.material.emissive.setHex(emissive);
            cubeData.mesh.material.needsUpdate = true;

            // 更新原始颜色记录
            cubeData.originalColor = color;
            cubeData.originalEmissive = emissive;

            // 更新数据
            if (cargoData[position]) {
                cargoData[position].hasGoods = hasGoods;
            }
            break;
        }
    }
}



// 销售出货操作
const handleSales = () => {
    console.log(`销售出货 - 货位: ${selectedCargoPosition.value}`);
    // 这里添加实际的销售出货逻辑
    // closeContextMenu();
}
// 领用库存操作
const handleInventory = () => {
    console.log(`领用库存 - 货位: ${selectedCargoPosition.value}`);
    // 这里添加实际的领用库存逻辑
    // closeContextMenu();
}

// 质检操作
const handleInspection = () => {
    console.log(`质检 - 货位: ${selectedCargoPosition.value}`);
    // 这里添加实际的质检逻辑
    // closeContextMenu();
}

// 查看详情操作
const handleDetails = () => {
    console.log('查看详情 - 货位: ', selectedCargoPosition.value);
    // 这里可以展开显示更详细的信息
    // closeContextMenu();
}
// 先加载纹理
const loadTextures = () => {
    return new Promise((resolve) => {
        textureLoader.load('src/assets/images/plane.png', (texture) => {
            // 正确设置纹理参数，避免发白问题
            texture.minFilter = THREE.LinearFilter;
            texture.magFilter = THREE.LinearFilter;
            texture.wrapS = THREE.ClampToEdgeWrapping;
            texture.wrapT = THREE.ClampToEdgeWrapping;
            texture.format = THREE.RGBAFormat;
            borderTexture = texture;
            // 加载地板纹理
            textureLoader.load('src/assets/images/floor.jpg', (floorTex) => {
                // 设置地板纹理参数
                floorTex.wrapS = THREE.RepeatWrapping;
                floorTex.wrapT = THREE.RepeatWrapping;
                floorTex.repeat.set(10, 10); // 根据需要调整重复次数
                // floorTex.minFilter = THREE.LinearFilter;
                // floorTex.magFilter = THREE.LinearFilter;
                floorTexture = floorTex;
                resolve();
            }, undefined, error => {
                console.log('地板纹理加载失败', error);
                resolve();
            });

        }, undefined, error => {
            console.log('边框纹理加载失败', error)
            // 即使边框纹理加载失败也尝试加载地板纹理
            textureLoader.load('src/assets/images/floor.png', (floorTex) => {
                floorTex.wrapS = THREE.RepeatWrapping;
                floorTex.wrapT = THREE.RepeatWrapping;
                floorTex.repeat.set(10, 10);
                floorTex.minFilter = THREE.LinearFilter;
                floorTex.magFilter = THREE.LinearFilter;
                floorTexture = floorTex;
                resolve();
            }, undefined, error => {
                console.log('地板纹理加载失败', error);
                resolve();
            });
        })
    })
}

const init = async () => {
    // 初始化场景
    scene = new THREE.Scene()
    scene.background = new THREE.Color(0x87CEEB)

    // 初始化射线检测器和鼠标对象
    raycaster = new THREE.Raycaster();
    mouse = new THREE.Vector2();

    // 初始化相机
    camera = new THREE.PerspectiveCamera(
        45,
        container.value.clientWidth / container.value.clientHeight,
        0.1,
        1000
    )
    camera.position.set(0, 8, 15) // 调整相机位置以更好地查看场景
    camera.lookAt(new THREE.Vector3(0, 0, 0))

    // 初始化渲染器
    renderer = new THREE.WebGLRenderer({
        antialias: true,
    })
    renderer.setSize(container.value.clientWidth, container.value.clientHeight)

    // 启用色调映射和伽马校正
    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.toneMappingExposure = 1;
    renderer.outputEncoding = THREE.sRGBEncoding;
    document.querySelector('.cube-scene').appendChild(renderer.domElement);

    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.8)
    scene.add(ambientLight)
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2)
    directionalLight.position.set(5, 12, 8)
    directionalLight.castShadow = true
    scene.add(directionalLight)
    const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.6);
    hemisphereLight.position.set(0, 20, 0);
    scene.add(hemisphereLight);


    // 创建图片纹理地面
    createTiledFloor()
    // 创建围墙
    createWalls()

    // 添加轨道控制器
    const { OrbitControls } = await import('three/examples/jsm/controls/OrbitControls.js')
    controls = new OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
    controls.dampingFactor = 0.05

    // 添加事件监听器
    window.addEventListener('resize', onWindowResize)
}

// 创建图片纹理地面
const createTiledFloor = () => {
    // 创建地面材质
    const floorMaterial = new THREE.MeshBasicMaterial({
        map: floorTexture,
        side: THREE.DoubleSide
    })

    // 创建地面几何体
    const floorGeometry = new THREE.PlaneGeometry(20, 20)
    const floor = new THREE.Mesh(floorGeometry, floorMaterial)
    floor.rotation.x = -Math.PI / 2 // 旋转使平面水平
    floor.receiveShadow = true
    scene.add(floor)
    // 创建一个不可见的平面用于检测点击位置
    const floorPlaneGeometry = new THREE.PlaneGeometry(20, 20);
    const floorPlaneMaterial = new THREE.MeshBasicMaterial({
        visible: false,
        side: THREE.DoubleSide
    });
    floorPlane.value = new THREE.Mesh(floorPlaneGeometry, floorPlaneMaterial);
    floorPlane.value.rotation.x = -Math.PI / 2;
    floorPlane.value.position.y = 0.01;
    floorPlane.value.userData.isFloor = true;
    scene.add(floorPlane.value);
}

// 开始放置货架
const startShelfPlacement = () => {
    isPlacingShelf.value = true;

    // 创建预览货架
    createPreviewShelf();
    // 添加鼠标移动监听
    renderer.domElement.addEventListener('mousemove', onMouseMove);
};

// 创建预览货架
const createPreviewShelf = () => {
    if (previewShelf) {
        scene.remove(previewShelf);
    }

    // 计算货架总尺寸
    const totalWidth = newShelfConfig.columns * newShelfConfig.columnWidth;
    const totalHeight = newShelfConfig.levels * newShelfConfig.levelHeight;
    const totalDepth = newShelfConfig.depth * newShelfConfig.depthLength;

    // 创建预览货架几何体
    const shelfGeometry = new THREE.BoxGeometry(totalWidth, totalHeight, totalDepth);
    const previewMaterial = new THREE.MeshPhongMaterial({
        color: 0x00ff00,
        transparent: true,
        opacity: 0.5
    });

    previewShelf = new THREE.Mesh(shelfGeometry, previewMaterial);
    previewShelf.visible = false;
    previewShelf.userData.isPreview = true;
    scene.add(previewShelf);

};


// 鼠标移动事件处理
const onMouseMove = (event) => {
    if (!isPlacingShelf.value || !previewShelf) return;

    // 计算鼠标位置
    const rect = renderer.domElement.getBoundingClientRect();
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    // 检测与地板的交点
    raycaster.setFromCamera(mouse, camera);
    const intersects = raycaster.intersectObject(floorPlane.value);

    if (intersects.length > 0) {
        const position = intersects[0].point;

        // 检查是否在边界内
        canPlaceShelf.value = checkShelfBoundary(position, newShelfConfig);

        // 更新预览货架位置和颜色
        previewShelf.position.copy(position);
        previewShelf.visible = true;

        // 根据是否可放置设置颜色
        previewShelf.material.color.setHex(canPlaceShelf.value ? 0x00ff00 : 0xff0000);
    }
};
// 检查货架是否在边界内
const checkShelfBoundary = (position, shelfConfig) => {
    const totalWidth = shelfConfig.columns * shelfConfig.columnWidth;
    const totalDepth = shelfConfig.depth * shelfConfig.depthLength;
    const halfWidth = totalWidth / 2;
    const halfDepth = totalDepth / 2;

    // 计算货架的边界
    const shelfMinX = position.x - halfWidth;
    const shelfMaxX = position.x + halfWidth;
    const shelfMinZ = position.z - halfDepth;
    const shelfMaxZ = position.z + halfDepth;

    // 检查是否超出仓库边界
    return (
        shelfMinX >= warehouseBounds.minX &&
        shelfMaxX <= warehouseBounds.maxX &&
        shelfMinZ >= warehouseBounds.minZ &&
        shelfMaxZ <= warehouseBounds.maxZ
    );
};
// 创建围墙函数 - 纯白色
const createWalls = () => {
    // 创建纯白色材质
    const wallMaterial = new THREE.MeshStandardMaterial({
        color: 0xffffff,
        roughness: 0.7,
        metalness: 0.1
    });

    // 创建四面墙
    const wallGroup = new THREE.Group();

    // 后墙
    const backWall = new THREE.Mesh(
        new THREE.BoxGeometry(20, 1.5, 0.3),
        wallMaterial
    );
    backWall.position.z = -10;
    backWall.position.y = 0.75;
    wallGroup.add(backWall);
    walls.push(backWall);

    // 前墙（留出门的空间）
    const frontWall = new THREE.Mesh(
        new THREE.BoxGeometry(16, 1.5, 0.3),
        wallMaterial
    );
    frontWall.position.z = 10;
    frontWall.position.y = 0.75;
    frontWall.position.x = 2;
    wallGroup.add(frontWall);
    walls.push(frontWall);


    // 左墙
    const leftWall = new THREE.Mesh(
        new THREE.BoxGeometry(0.3, 1.5, 20),
        wallMaterial
    );
    leftWall.position.x = -10;
    leftWall.position.y = 0.75;
    wallGroup.add(leftWall);
    walls.push(leftWall);

    // 右墙
    const rightWall = new THREE.Mesh(
        new THREE.BoxGeometry(0.3, 1.5, 20),
        wallMaterial
    );
    rightWall.position.x = 10;
    rightWall.position.y = 0.75;
    wallGroup.add(rightWall);
    walls.push(rightWall);

    scene.add(wallGroup);
}

// 创建货架函数
const createShelf = (config, name, position, rotation) => {
    const shelf = new THREE.Group();

    // 设置位置和旋转
    shelf.position.set(position.x, position.y, position.z)
    shelf.rotation.set(rotation.x, rotation.y, rotation.z)

    // 计算货架总尺寸
    const totalWidth = config.columns * config.columnWidth;
    const totalHeight = config.levels * config.levelHeight;
    const totalDepth = config.depth * config.depthLength;

    // 创建支柱（圆柱体）
    const pillarGeometry = new THREE.CylinderGeometry(0.05, 0.05, totalHeight, 16);
    const pillarMaterial = new THREE.MeshPhongMaterial({ color: config.pillarColor });

    // 四个角的支柱
    const pillars = [
        { x: -totalWidth / 2, z: -totalDepth / 2 },
        { x: totalWidth / 2, z: -totalDepth / 2 },
        { x: totalWidth / 2, z: totalDepth / 2 },
        { x: -totalWidth / 2, z: totalDepth / 2 }
    ];

    pillars.forEach(pos => {
        const pillar = new THREE.Mesh(pillarGeometry, pillarMaterial);
        pillar.position.set(pos.x, totalHeight / 2, pos.z);
        shelf.add(pillar);


    });

    // 创建层板（长方体）
    const shelfMaterial = new THREE.MeshPhongMaterial({ color: config.shelfColor });
    for (let level = 0; level < config.levels; level++) {
        const yPos = level * config.levelHeight;

        // 主层板
        const shelfGeometry = new THREE.BoxGeometry(totalWidth, 0.05, totalDepth);
        const shelfMesh = new THREE.Mesh(shelfGeometry, shelfMaterial);
        shelfMesh.position.y = yPos;
        shelf.add(shelfMesh);

        // 使用图片纹理替代黄色线框
        addImageBorders(totalWidth - 0.1, totalDepth - 0.1, config.columns, config.depth, yPos + 0.03, shelf);
        // 为每个货位创建立方体货物
        createCargoCubes(totalWidth, totalDepth, config.columns, config.depth, yPos, shelf, name, level);

    }

    // 添加货架顶框
    const topFrameGeometry = new THREE.BoxGeometry(totalWidth + 0.2, 0.2, totalDepth + 0.2);
    const topFrameMesh = new THREE.Mesh(topFrameGeometry, shelfMaterial);
    topFrameMesh.position.y = totalHeight;
    shelf.add(topFrameMesh);

    // 添加货架标签
    addShelfLabel(shelf, config, name);
    return shelf;
}


// 为每个货位创建立方体货物
const createCargoCubes = (totalWidth, totalDepth, columns, depth, yPos, shelf, shelfName, level) => {
    const cellWidth = totalWidth / columns;
    const cellDepth = totalDepth / depth;

    // 货物立方体尺寸（略小于货位格子）
    const cubeWidth = cellWidth * 0.8;
    const cubeHeight = 0.3; // 货物高度
    const cubeDepth = cellDepth * 0.8;

    for (let col = 0; col < columns; col++) {
        for (let dep = 0; dep < depth; dep++) {
            // 计算货位中心位置
            const xPos = -totalWidth / 2 + col * cellWidth + cellWidth / 2;
            const zPos = -totalDepth / 2 + dep * cellDepth + cellDepth / 2;
            // 货位标识符
            const position = `${shelfName}-${level + 1}-${col + 1}-${dep + 1}`;

            // 获取货物数据（如果没有则创建默认数据）
            const cargoInfo = cargoData[position] || {
                hasGoods: false,
                name: '',
                materialCode: ''
            };
            console.log(position, '货物信息')
            // 创建立方体几何体
            const geometry = new THREE.BoxGeometry(cubeWidth, cubeHeight, cubeDepth);

            // 根据货物状态设置颜色
            const color = cargoInfo.hasGoods ? 0x00ff00 : 0xff0000; // 绿色有货，红色无货
            const material = new THREE.MeshPhongMaterial({
                color: color,
                emissive: cargoInfo.hasGoods ? 0x003300 : 0x330000, // 微弱自发光
                transparent: true,
                opacity: cargoInfo.hasGoods ? 1 : 1 //盒子透明度
            });

            // 创建立方体网格
            const cube = new THREE.Mesh(geometry, material);
            cube.position.set(xPos, yPos + cubeHeight / 2 + 0.03, zPos);

            // 添加用户数据，用于识别
            cube.userData = {
                isCargoCube: true,
                position: position,
                cargoInfo: cargoInfo
            };
            addCargoLabel(cube, cargoInfo, position, cubeWidth, cubeHeight, cubeDepth);


            // 添加到货架
            shelf.add(cube);

            // 存储立方体引用
            cargoCubes.push({
                mesh: cube,
                position: position,
                originalColor: color,
                originalEmissive: cargoInfo.hasGoods ? 0x003300 : 0x330000
            });
        }
    }
}

// 添加货物信息标签
const addCargoLabel = (cube, cargoInfo, position, width, height, depth) => {
    // 创建Canvas纹理
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');

    // 设置Canvas尺寸
    const canvasWidth = 256;
    const canvasHeight = 128;
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    // 绘制背景
    context.fillStyle = 'rgba(255, 255, 255, 0.9)';
    context.fillRect(0, 0, canvasWidth, canvasHeight);

    // 绘制边框
    context.strokeStyle = '#333';
    context.lineWidth = 2;
    context.strokeRect(2, 2, canvasWidth - 4, canvasHeight - 4);

    // 绘制文本
    context.fillStyle = '#000';
    context.font = 'bold 18px Arial';
    context.textAlign = 'center';

    // 货位信息
    context.fillText(`货位: ${position}`, canvasWidth / 2, 30);
    context.font = '16px Arial';
    // 货物名称
    if (cargoInfo.name) {
        context.fillText(`名称: ${cargoInfo.name}`, canvasWidth / 2, 60);
    }


    // 料号
    if (cargoInfo.materialCode) {
        context.fillText(`料号: ${cargoInfo.materialCode}`, canvasWidth / 2, 90);
    }

    // 状态
    context.fillStyle = cargoInfo.hasGoods ? 'green' : 'red';
    context.fillText(`状态: ${cargoInfo.hasGoods ? '有货' : '无货'}`, canvasWidth / 2, 120);

    // 创建纹理
    const texture = new THREE.CanvasTexture(canvas);
    texture.minFilter = THREE.LinearFilter;
    texture.magFilter = THREE.LinearFilter;

    // 创建标签材质
    const labelMaterial = new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true,
        side: THREE.DoubleSide
    });

    // 创建标签平面几何体
    const labelGeometry = new THREE.PlaneGeometry(width * 0.9, height * 0.8);

    // 创建标签网格
    const label = new THREE.Mesh(labelGeometry, labelMaterial);

    // 将标签放置在立方体的正面（Z方向）
    label.position.set(0, 0, depth / 2 + 0.01);
    label.rotation.x = 0; // 确保标签面向外部

    // 将标签添加到立方体
    cube.add(label);

    // 存储标签引用以便后续管理
    cube.userData.label = label;
};

// 处理画布点击事件
const onCanvasClick = (event) => {
    // 如果正在放置货架，处理放置逻辑
    if (isPlacingShelf.value && previewShelf && previewShelf.visible) {
        placeShelf();
        return;
    }
    // 计算鼠标在归一化设备坐标中的位置
    const rect = renderer.domElement.getBoundingClientRect();
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera(mouse, camera);

    // 计算物体和射线的交点
    const intersects = raycaster.intersectObjects(scene.children, true);

    // 查找货位交互平面
    for (let i = 0; i < intersects.length; i++) {
        const object = intersects[i].object;

        // 检查是否点击了货物立方体
        if (object.userData && object.userData.isCargoCube) {
            // 高亮选中的货物立方体
            highlightCargoCube(object);
            // 显示货物信息
            selectedCargo.value = {
                position: object.userData.position,
                name: object.userData.cargoInfo.name,
                materialCode: object.userData.cargoInfo.materialCode,
                hasGoods: object.userData.cargoInfo.hasGoods
            };
            console.log(selectedCargo.value, '货物信息')
            return;
        }


    }
    selectedCargo.value = null;

    // 取消所有货物立方体的高亮
    resetCargoCubesHighlight();
}
// 放置货架
const placeShelf = () => {
    if (!canPlaceShelf.value) {
        showBoundaryWarning.value = true;
        setTimeout(() => {
            showBoundaryWarning.value = false;
        }, 2000);
        return;
    }
    // 创建实际货架
    const shelfName = `自定义货架${shelfCounter.value++}`;
    const shelf = createShelf(
        newShelfConfig,
        shelfName,
        previewShelf.position,
        { x: 0, y: 0, z: 0 }
    );

    scene.add(shelf);
    shelves.push(shelf);

    // 清理预览状态
    cancelShelfPlacement();
};
// 取消放置货架
const cancelShelfPlacement = () => {
    isPlacingShelf.value = false;
    canPlaceShelf.value = false;
    // 移除预览货架
    if (previewShelf) {
        scene.remove(previewShelf);
        previewShelf = null;
    }

    // 移除鼠标移动监听
    renderer.domElement.removeEventListener('mousemove', onMouseMove);
};
// 添加货架标签
const addShelfLabel = (shelf, config, name) => {

    // 创建Canvas纹理
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    canvas.width = 256;
    canvas.height = 94;

    // 绘制背景和文本
    context.fillStyle = 'rgba(0, 0, 0, 0.8)';
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.font = 'bold 20px Arial';
    context.fillStyle = 'white';
    context.textAlign = 'center';
    context.textBaseline = 'middle';

    const shelfName = name;

    const shelfSize = `(${config.columns}×${config.levels}×${config.depthLength})`;

    context.fillText(shelfName, canvas.width / 2, canvas.height / 2 - 10);
    context.font = '16px Arial';
    context.fillText(shelfSize, canvas.width / 2, canvas.height / 2 + 10);

    // 创建纹理和材质
    const texture = new THREE.CanvasTexture(canvas);
    const material = new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true,
        side: THREE.DoubleSide
    });

    // 创建平面几何体
    const labelGeometry = new THREE.PlaneGeometry(config.columns * config.columnWidth * 0.8, 0.3);
    const labelMesh = new THREE.Mesh(labelGeometry, material);

    // 将标签放置在货架顶部中央
    labelMesh.position.set(0, config.levels * config.levelHeight + 0.15, 0);
    // labelMesh.rotation.x = Math.PI; 

    shelf.add(labelMesh);
    shelfLabels.push(labelMesh);
}



// 使用图片纹理替代黄色线框
const addImageBorders = (totalWidth, totalDepth, columns, depth, yPos, shelf) => {
    const cellWidth = totalWidth / columns;
    const cellDepth = totalDepth / depth;

    // 创建边框材质
    let borderMaterial;

    if (borderTexture) {
        borderMaterial = new THREE.MeshBasicMaterial({
            map: borderTexture,
            transparent: true,
            alphaTest: 0.1, // 设置alpha测试阈值，避免边缘发白
            side: THREE.DoubleSide
        });
    } else {
        // 后备方案：使用黄色线框
        const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffff00 });

        // 创建纵向线（列分隔线）
        for (let col = 1; col < columns; col++) {
            const xPos = -totalWidth / 2 + col * shelfConfig.value.columnWidth;

            const points = [];
            points.push(new THREE.Vector3(xPos, yPos, -totalDepth / 2));
            points.push(new THREE.Vector3(xPos, yPos, totalDepth / 2));

            const lineGeometry = new THREE.BufferGeometry().setFromPoints(points);
            const line = new THREE.Line(lineGeometry, lineMaterial);
            shelf.add(line);
        }

        // // 创建横向线（深度分隔线）
        for (let d = 1; d < depth; d++) {
            const zPos = -totalDepth / 2 + d * shelfConfig.value.depthLength;
            const points = [];
            points.push(new THREE.Vector3(-totalWidth / 2, yPos, zPos));
            points.push(new THREE.Vector3(totalWidth / 2, yPos, zPos));
            const lineGeometry = new THREE.BufferGeometry().setFromPoints(points);
            const line = new THREE.Line(lineGeometry, lineMaterial);
            shelf.add(line);
        }

        // 创建外边框
        const borderPoints = [
            new THREE.Vector3(-totalWidth / 2, yPos, -totalDepth / 2),
            new THREE.Vector3(totalWidth / 2, yPos, -totalDepth / 2),
            new THREE.Vector3(totalWidth / 2, yPos, totalDepth / 2),
            new THREE.Vector3(-totalWidth / 2, yPos, totalDepth / 2),
            new THREE.Vector3(-totalWidth / 2, yPos, -totalDepth / 2)
        ];

        const borderGeometry = new THREE.BufferGeometry().setFromPoints(borderPoints);
        const border = new THREE.Line(borderGeometry, lineMaterial);
        shelf.add(border);

        return;
    }

    for (let col = 0; col < columns; col++) {
        for (let dep = 0; dep < depth; dep++) {
            const xPos = -totalWidth / 2 + col * cellWidth + cellWidth / 2;
            const zPos = -totalDepth / 2 + dep * cellDepth + cellDepth / 2;

            // 创建边框平面
            const borderGeometry = new THREE.PlaneGeometry(cellWidth - 0.02, cellDepth - 0.02);
            const borderMesh = new THREE.Mesh(borderGeometry, borderMaterial);
            borderMesh.position.set(xPos, yPos, zPos);
            borderMesh.rotation.x = -Math.PI / 2; // 旋转到水平

            shelf.add(borderMesh);
        }
    }
}



// 高亮选中的货物立方体
const highlightCargoCube = (cube) => {
    // 首先取消所有立方体的高亮
    resetCargoCubesHighlight();

    // 高亮选中的立方体
    cube.material.emissive.set(0x888888); // 增加自发光强度
    cube.material.needsUpdate = true;

    // 存储当前选中的立方体
    selectedCell = cube;
}

// 取消所有货物立方体的高亮
const resetCargoCubesHighlight = () => {
    cargoCubes.forEach(cubeData => {
        const cube = cubeData.mesh;
        cube.material.emissive.set(cubeData.originalEmissive);
        cube.material.needsUpdate = true;
    });
}


// 释放对象资源
const disposeObject = (obj) => {
    console.log(obj, '释放对象资源')
    obj.traverse(child => {
        if (child.isMesh) {
            child.geometry.dispose();
            if (child.material) {
                if (Array.isArray(child.material)) {
                    child.material.forEach(material => material.dispose());
                } else {
                    child.material.dispose();
                }
            }
        }
    });
}

// 生成货架布局
const generateShelves = () => {
    // 清除现有货架
    shelves.forEach(shelf => {
        scene.remove(shelf)
    })
    shelves = []

    // 清除现有标签
    cellLabels.forEach(label => {
        scene.remove(label)
    })
    cellLabels = []
    // 清除现有货架标签
    shelfLabels.forEach(label => {
        scene.remove(label)
    })
    shelfLabels = []

    let name = ''
    const startX = -(cols.value - 1) * spacing.value / 2
    const startZ = -(rows.value - 1) * spacing.value / 2
    for (let row = 0; row < rows.value; row++) {
        for (let col = 0; col < cols.value; col++) {
            const x = startX + col * spacing.value
            const z = startZ + row * spacing.value
            name = `货架${row + 1}-${col + 1}`
            const shelf = createShelf(
                shelfConfig.value,
                name,
                { x, y: 0, z },
                { x: 0, y: 0, z: 0 }
            )

            scene.add(shelf)
            shelves.push(shelf)
        }
    }
}

// 监听布局参数变化 
watch([rows, cols, spacing], () => {
    generateShelves()
})

const onWindowResize = () => {
    camera.aspect = container.value.clientWidth / container.value.clientHeight
    camera.updateProjectionMatrix()
    renderer.setSize(container.value.clientWidth, container.value.clientHeight)
}

const animate = () => {
    requestAnimationFrame(animate)

    // 更新控制器
    if (controls) {
        controls.update()
    }

    renderer.render(scene, camera)
}
defineExpose({
    startShelfPlacement
})
</script>

<style lang="scss" scoped>
.cube-scene {
    width: 100%;
    height: 100%;
    position: relative;
}

/* 货物信息弹窗样式 */
.cargo-info-popup {
    position: absolute;
    top: 20px;
    right: 20px;
    background: rgba(255, 255, 255, 0.9);
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    max-width: 300px;
    z-index: 100;
    height: calc(100% - 40px);
    overflow-y: scroll;
}

.cargo-info-popup h3 {
    margin-top: 0;
    border-bottom: 1px solid #eee;
    padding-bottom: 8px;
    color: #2196F3;
}

.cargo-info-popup p {
    margin: 8px 0;
    line-height: 1.4;
    color: #000;
}

.info-text {
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.5);
    padding: 10px 20px;
    border-radius: 5px;
    font-size: 1.2rem;
    color: white;
}

/* 右击操作菜单样式 */
.context-menu {
    position: fixed;
    background: white;
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    padding: 15px;
    min-width: 200px;
    z-index: 1000;

    .iconClose {
        cursor: pointer;
        position: absolute;
        top: 15px;
        right: 15px;
    }
}

.context-menu h4 {
    margin: 0 0 12px 0;
    padding-bottom: 10px;
    border-bottom: 1px solid #eee;
    color: #2196F3;
    font-size: 16px;
}

.optionsMenu {
    width: 220px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;

    .switch {
        width: 100%;
        margin-bottom: 8px;
    }

    >Button {
        margin-bottom: 8px;
    }
}


/* 放置提示样式 */
.placement-hint {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 10px 15px;
    border-radius: 5px;
    text-align: center;
}

/* 控制按钮样式 */
.control-buttons {
    position: absolute;
    bottom: 20px;
    right: 20px;
    display: flex;
    gap: 10px;
    z-index: 100;
}

/* 边界警告样式 */
.boundary-warning {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(255, 0, 0, 0.8);
    color: white;
    padding: 15px;
    border-radius: 8px;
    text-align: center;
    z-index: 1000;
    animation: pulse 1.5s infinite;
}

@keyframes pulse {
    0% {
        opacity: 0.7;
    }

    50% {
        opacity: 1;
    }

    100% {
        opacity: 0.7;
    }
}

.placement-hint p {
    margin: 0 0 10px 0;
}
</style>